#!/usr/bin/env python
# -*- coding: utf-8 -*-
# time: 2022/11/15 13:05
# file: login.py
# author: lotus163
import datetime

from .role_dept import RoleDeptService
from .role_menu import RoleMenuService
from .scope import DataScopeService
from .user import UserService
from ..monitor.login_infor import LoginInforService
from ...core.custom_exc import LoginException
from ...core.deps import LoginDepends
from ...core.redis import MyRedis
from ...core.request import RequestService
from ...core.security import verify_password, get_expires, create_access_token
from ...crud import UserDao
from ...schemas import LoginForm, LoginUserSch, LoginInforSch


class LoginService:
    """登录Service"""

    def __init__(self, form: LoginForm, login_depends: LoginDepends):
        self.form: LoginForm = form
        self.login_depends: LoginDepends = login_depends
        self.request_service: RequestService = login_depends.request_service
        self.redis: MyRedis = login_depends.redis

    async def validate_login_and_get_token(self) -> str:
        # 从数据库读取user
        user_db = await UserDao.get_db_or_none(userName=self.form.username)
        if user_db is None:
            raise LoginException("用户不存在")
        if not verify_password(self.form.password, user_db.password):
            raise LoginException("密码错误")
        if user_db.status == "1":
            raise LoginException("用户已停用")

        # 过期时间
        expires = get_expires()
        # 生成token
        token = create_access_token(data={"login_user_key": self.form.uuid, "sub": user_db.userName},
                                    expires=expires)
        # 过期时间的时间戳,因为带小数，转成int
        expireTime=int(expires.timestamp())
        login_infor_sch = LoginInforSch(userName=self.form.username,
                                        ipaddr=self.request_service.get_ip_addr(),
                                        loginLocation=self.request_service.get_ip_location(),
                                        browser=self.request_service.get_browser(),
                                        os=self.request_service.get_os(),
                                        loginTime=datetime.datetime.now()
                                        )
        # 保存到数据库
        await LoginInforService().add_login_infor(login_infor_sch)
        # 保存到redis
        await self.redis.save_login_tokens(login_infor_sch,token,expireTime,self.form.uuid)
        return token
